Skip to content

chore(tracing): support for open telemetry traces - #4855

Merged
aleks-p merged 21 commits into
mainfrom
chore/switch-to-otel-tracing
Mar 31, 2026
Merged

chore(tracing): support for open telemetry traces#4855
aleks-p merged 21 commits into
mainfrom
chore/switch-to-otel-tracing

Conversation

@aleks-p

@aleks-p aleks-p commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

See #4127 and #4178.

Migrates all tracing instrumentation from OpenTracing to OpenTelemetry, using dskit's tracing.StartSpanFromContext bridge for span creation and dskit's NewOTelOrJaegerFromEnv for tracer initialization.

Includes an E2E verification tool (tools/tracing/verify.sh) that starts Pyroscope + Tempo, sends traffic, and asserts write-path and read-path traces appear in Tempo via TraceQL.

Existing Jaeger deployments continue to work without config changes, dskit auto-detects JAEGER_* env vars and configures Jaeger exporters via the OTel SDK. Trace export can be disabled entirely with OTEL_TRACES_EXPORTER=none.

TODO:

  • go over the diff
  • deploy in a dev environment and verify traces are flowing

Note

Medium Risk
Large dependency upgrades (observability stack, networking/memberlist, cloud SDKs) can introduce subtle runtime behavior changes despite most code changes here being documentation/help regeneration.

Overview
Refreshes generated CLI help (help.txt.tmpl, help-all.txt.tmpl) and configuration reference docs to document new flags/options, including -server.create-new-traces, gRPC per-connection buffer sizing, expanded trace-header exclusion defaults, memberlist join parsing and new experimental memberlist knobs (fast-join min nodes, rejoin seed nodes, zone-aware routing, propagation delay tracker), and server.cluster-validation.additional-labels.

Updates tracing examples/docs to reference OpenTelemetry (otel-profiling-go) instead of OpenTracing, and bumps Go/tooling + a large set of dependencies (notably dskit, OpenTelemetry stack, Prometheus, AWS SDK, and memberlist fork) to versions consistent with the updated tracing/membership behavior.

Written by Cursor Bugbot for commit 00d32bf. This will update automatically on new commits. Configure here.

@aleks-p aleks-p changed the title chore(tracing): switch from OpenTracing to OpenTelemetry chore(tracing): support for open telemetry traces Feb 20, 2026
@aleks-p
aleks-p force-pushed the chore/switch-to-otel-tracing branch 2 times, most recently from 5dd0d16 to 35d8369 Compare March 19, 2026 16:44
@aleks-p
aleks-p marked this pull request as ready for review March 20, 2026 19:23

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for 2 of the 3 issues found in the latest run.

  • ✅ Fixed: SetTag in loop overwrites per-row-group trace data
    • Replaced SetTag calls in the loop with AddEvent to create separate trace events per row-group iteration, preserving all header metadata.
  • ✅ Fixed: Batch-level trace data lost due to tag overwrite
    • Replaced SetTag calls in the batch callback with AddEvent to create separate trace events per batch, preserving all batch processing data.

Create PR

Or push these changes by commenting:

@cursor push 3800cfff2c
Preview (3800cfff2c)
diff --git a/pkg/phlaredb/filter_profiles_bidi.go b/pkg/phlaredb/filter_profiles_bidi.go
--- a/pkg/phlaredb/filter_profiles_bidi.go
+++ b/pkg/phlaredb/filter_profiles_bidi.go
@@ -8,6 +8,7 @@
 	"github.com/grafana/dskit/tracing"
 	"github.com/pkg/errors"
 	"github.com/prometheus/common/model"
+	"go.opentelemetry.io/otel/attribute"
 	oteltrace "go.opentelemetry.io/otel/trace"
 
 	ingestv1 "github.com/grafana/pyroscope/api/gen/proto/go/ingester/v1"
@@ -82,8 +83,10 @@
 		Profile: maxBlockProfile,
 		Index:   0,
 	}, true, its...), batchProfileSize, func(ctx context.Context, batch []ProfileWithIndex) error {
-		sp.SetTag("batch_len", len(batch))
-		sp.SetTag("batch_requested_size", batchProfileSize)
+		otelSpan.AddEvent("processing batch", oteltrace.WithAttributes(
+			attribute.Int("batch_len", len(batch)),
+			attribute.Int("batch_requested_size", batchProfileSize),
+		))
 
 		seriesByFP := map[model.Fingerprint]int{}
 		selectProfileResult.Profiles = selectProfileResult.Profiles[:0]

diff --git a/pkg/phlaredb/symdb/block_reader_parquet.go b/pkg/phlaredb/symdb/block_reader_parquet.go
--- a/pkg/phlaredb/symdb/block_reader_parquet.go
+++ b/pkg/phlaredb/symdb/block_reader_parquet.go
@@ -10,6 +10,8 @@
 	"github.com/grafana/dskit/multierror"
 	"github.com/grafana/dskit/tracing"
 	"github.com/parquet-go/parquet-go"
+	"go.opentelemetry.io/otel/attribute"
+	oteltrace "go.opentelemetry.io/otel/trace"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/grafana/pyroscope/pkg/objstore"
@@ -40,10 +42,11 @@
 )
 
 func (t *parquetTable[M, P]) fetch(ctx context.Context) (err error) {
-	span, _ := tracing.StartSpanFromContext(ctx, "parquetTable.fetch")
+	span, spanCtx := tracing.StartSpanFromContext(ctx, "parquetTable.fetch")
 	span.SetTag("table_name", t.persister.Name())
 	span.SetTag("row_groups", len(t.headers))
 	defer span.Finish()
+	otelSpan := oteltrace.SpanFromContext(spanCtx)
 	return t.r.Inc(func() error {
 		var s uint32
 		for _, h := range t.headers {
@@ -55,9 +58,11 @@
 		// TODO(kolesnikovae): Row groups could be fetched in parallel.
 		rgs := t.file.RowGroups()
 		for _, h := range t.headers {
-			span.SetTag("row_group", h.RowGroup)
-			span.SetTag("index_row", h.Index)
-			span.SetTag("rows", h.Rows)
+			otelSpan.AddEvent("row_group_fetch", oteltrace.WithAttributes(
+				attribute.Int("row_group", int(h.RowGroup)),
+				attribute.Int("index_row", int(h.Index)),
+				attribute.Int("rows", int(h.Rows)),
+			))
 			rg := rgs[h.RowGroup]
 			rows := rg.Rows()
 			if err := rows.SeekToRow(int64(h.Index)); err != nil {

Comment thread pkg/metastore/tracing/util.go
Comment thread pkg/phlaredb/symdb/block_reader_parquet.go Outdated
Comment thread pkg/phlaredb/filter_profiles_bidi.go Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Span tag "msg" misused for log events
    • Replaced SetTag('msg', ...) with trace.SpanFromContext(...).AddEvent(...) in bucket_compactor.go and ingest_handler.go to properly record log-level messages as timestamped span events instead of static metadata tags.
  • ✅ Fixed: Dropped shouldSymbolize span event in symbolizer migration
    • Restored the missing otelSpan.AddEvent("shouldSymbolize") call in symbolizer.go to preserve tracing visibility into symbolization decisions.

Create PR

Or push these changes by commenting:

@cursor push c11766d601
Preview (c11766d601)
diff --git a/pkg/compactor/bucket_compactor.go b/pkg/compactor/bucket_compactor.go
--- a/pkg/compactor/bucket_compactor.go
+++ b/pkg/compactor/bucket_compactor.go
@@ -927,8 +927,8 @@
 			case jobChan <- g:
 			case <-maxCompactionTimeChan:
 				maxCompactionTimeReached = true
-				level.Info(c.logger).Log("msg", "max compaction time reached, no more compactions will be started")
-				sp.SetTag("msg", "max compaction time reached, no more compactions will be started")
+			level.Info(c.logger).Log("msg", "max compaction time reached, no more compactions will be started")
+			trace.SpanFromContext(workCtx).AddEvent("max compaction time reached, no more compactions will be started")
 				break jobLoop
 			}
 		}

diff --git a/pkg/frontend/readpath/queryfrontend/symbolizer.go b/pkg/frontend/readpath/queryfrontend/symbolizer.go
--- a/pkg/frontend/readpath/queryfrontend/symbolizer.go
+++ b/pkg/frontend/readpath/queryfrontend/symbolizer.go
@@ -119,6 +119,7 @@
 // profiles exist.
 func (q *QueryFrontend) shouldSymbolize(ctx context.Context, tenants []string, blocks []*metastorev1.BlockMeta) bool {
 	otelSpan := oteltrace.SpanFromContext(ctx)
+	otelSpan.AddEvent("shouldSymbolize")
 
 	if q.symbolizer == nil {
 		return false

diff --git a/pkg/ingester/pyroscope/ingest_handler.go b/pkg/ingester/pyroscope/ingest_handler.go
--- a/pkg/ingester/pyroscope/ingest_handler.go
+++ b/pkg/ingester/pyroscope/ingest_handler.go
@@ -61,7 +61,7 @@
 		msg := "failed to parse request metadata"
 		sp.LogError(err)
 		sp.SetError()
-		sp.SetTag("msg", msg)
+		trace.SpanFromContext(ctx).AddEvent(msg)
 		_ = h.log.Log("msg", msg, "err", err, "orgID", tenantID)
 		httputil.ErrorWithStatus(w, err, http.StatusBadRequest)
 		return
@@ -83,7 +83,7 @@
 		msg := "failed to read request body"
 		sp.LogError(err)
 		sp.SetError()
-		sp.SetTag("msg", msg)
+		trace.SpanFromContext(ctx).AddEvent(msg)
 		_ = h.log.Log("msg", msg, "err", err, "orgID", tenantID)
 		httputil.ErrorWithStatus(w, err, status)
 		return
@@ -95,14 +95,14 @@
 			msg := "failed to convert profile"
 			sp.LogError(err)
 			sp.SetError()
-			sp.SetTag("msg", msg)
+			trace.SpanFromContext(ctx).AddEvent(msg)
 			_ = h.log.Log("msg", msg, "err", err, "orgID", tenantID)
 			httputil.Error(w, err)
 		} else {
 			msg := "failed to ingest profile"
 			sp.LogError(err)
 			sp.SetError()
-			sp.SetTag("msg", msg)
+			trace.SpanFromContext(ctx).AddEvent(msg)
 			httputil.ErrorWithStatus(w, err, http.StatusUnprocessableEntity)
 		}
 	}

Comment thread pkg/compactor/bucket_compactor.go Outdated
Comment thread pkg/frontend/readpath/queryfrontend/symbolizer.go

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Span tags overwrite per-iteration data in compaction loop
    • Replaced sp.SetTag calls with trace.SpanFromContext(ctx).AddEvent() to create separate timestamped log entries per iteration instead of overwriting span attributes.

Create PR

Or push these changes by commenting:

@cursor push 148c60a7d9
Preview (148c60a7d9)
diff --git a/pkg/compactor/bucket_compactor.go b/pkg/compactor/bucket_compactor.go
--- a/pkg/compactor/bucket_compactor.go
+++ b/pkg/compactor/bucket_compactor.go
@@ -875,7 +875,7 @@
 			sp.SetError()
 			return errors.Wrap(err, "build compaction jobs")
 		}
-		sp.SetTag("discovered_jobs", len(jobs))
+		discoveredJobs := len(jobs)
 
 		// There is another check just before we start processing the job, but we can avoid sending it
 		// to the goroutine in the first place.
@@ -883,7 +883,7 @@
 		if err != nil {
 			return err
 		}
-		sp.SetTag("own_jobs", len(jobs))
+		ownJobs := len(jobs)
 
 		// Record the difference between now and the max time for a block being compacted. This
 		// is used to detect compactors not being able to keep up with the rate of blocks being
@@ -895,8 +895,17 @@
 
 		// Skip jobs for which the wait period hasn't been honored yet.
 		jobs = c.filterJobsByWaitPeriod(ctx, jobs)
-		sp.SetTag("filtered_jobs", len(jobs))
+		filteredJobs := len(jobs)
 
+		// Use AddEvent instead of SetTag to preserve per-iteration data as separate
+		// timestamped log entries, rather than overwriting previous iteration values.
+		trace.SpanFromContext(ctx).AddEvent("compaction iteration jobs",
+			trace.WithAttributes(
+				attribute.Int("discovered_jobs", discoveredJobs),
+				attribute.Int("own_jobs", ownJobs),
+				attribute.Int("filtered_jobs", filteredJobs),
+			))
+
 		// Sort jobs based on the configured ordering algorithm.
 		jobs = c.sortJobs(jobs)

Comment thread pkg/compactor/bucket_compactor.go Outdated
@aleks-p
aleks-p force-pushed the chore/switch-to-otel-tracing branch from 8080d6e to 083d5e9 Compare March 24, 2026 14:04

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.

Comment thread pkg/phlaredb/compact.go
Comment thread pkg/compactor/bucket_compactor.go
@aleks-p
aleks-p requested a review from a team as a code owner March 24, 2026 16:05
@aleks-p
aleks-p force-pushed the chore/switch-to-otel-tracing branch from 15df28a to eed42af Compare March 24, 2026 18:18
@cla-assistant

cla-assistant Bot commented Mar 24, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cla-assistant

cla-assistant Bot commented Mar 24, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@aleks-p
aleks-p force-pushed the chore/switch-to-otel-tracing branch from eed42af to 1725fbe Compare March 25, 2026 11:58
}
series.Labels = append(series.Labels, &typesv1.LabelPair{
Name: labels.MetricName,
Name: string(prommodel.MetricNameLabel),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

originally deprecated in prometheus/prometheus#16228, more context in prometheus/prometheus#17590

cfg.Replacement = relabel.DefaultRelabelConfig.Replacement
}
require.NoError(t, cfg.Validate())
require.NoError(t, cfg.Validate(model.UTF8Validation))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model.UTF8Validation is the default, prometheus/prometheus#16928

Comment on lines -198 to +205
result, kept := relabel.Process(tc.input, defaultRelabelRules...)
require.Equal(t, tc.expected, result)
lb := labels.NewBuilder(tc.input)
kept := relabel.ProcessBuilder(lb, defaultRelabelRules...)
require.Equal(t, tc.expected, lb.Labels())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +6 to -14
"math/rand/v2"
"os"
"testing"
"time"

"connectrpc.com/connect"
"github.com/go-kit/log"
"github.com/grafana/dskit/user"
"github.com/stretchr/testify/require"
"golang.org/x/exp/rand"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


for idx, rule := range v {
if err := rule.Validate(); err != nil {
if err := rule.Validate(model.UTF8Validation); err != nil {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model.UTF8Validation is the default, prometheus/prometheus#16928

Comment thread go.mod
module github.com/grafana/pyroscope

go 1.24.9
go 1.25.7

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread pkg/util/http.go Outdated
if sp == nil {
sp, ctx = opentracing.StartSpanFromContext(ctx, "Compact")
}
sp, ctx := tracing.StartSpanFromContext(ctx, "Compact")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new code always creates a child "Compact" span. This changes trace structure (extra nesting level) and moves those attributes to a new child span. Is this intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked and there is no good API to achieve what we had here before, without it becoming too complex.

There is no tracing.SpanFromContext that returns a wrapped span (the existing method returns too many things and not the dskit's own wrapper).

I think it is simpler to keep it as is, and deal with an extra nested span. This is also v1, which is on the path to deprecation.

@bryanhuhta bryanhuhta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a peek at this. I think in general everything looks good. Maybe take a closer look at some of the hot path changes to make sure we don't introduce a performance regression.

Other than that, LGTM!

Comment thread pkg/util/httpgrpcutil/carrier.go Outdated
Comment thread pkg/phlaredb/query/iters.go Outdated
Comment thread pkg/phlaredb/query/iters.go Outdated
Comment thread pkg/phlaredb/query/repeated.go Outdated
Comment thread pkg/querybackend/query.go Outdated
Comment thread pkg/querybackend/query.go Outdated
Comment thread pkg/phlaredb/symdb/block_reader_parquet.go Outdated
Comment thread pkg/util/http.go Outdated
Comment thread pkg/pyroscope/tracing.go

@marcsanmi marcsanmi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

aleks-p and others added 6 commits March 31, 2026 08:44
Add tools/tracing/ with a self-contained setup that builds Pyroscope
from source, starts it alongside Tempo (via docker-compose), sends
real requests via profilecli, and asserts that write-path and read-path
traces appear in Tempo using TraceQL queries with retry logic.

Includes a Grafana instance for manual trace inspection (--interactive).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace opentracing.StartSpanFromContext with dskit tracing.StartSpanFromContext
in the write path and utility packages. dskit's tracing bridge creates spans
compatible with whichever tracer is registered (OpenTracing or OTel).

Packages: distributor, ingester, segmentwriter, spanlogger/query_log,
delayhandler, metastore/tracing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace opentracing.StartSpanFromContext with dskit tracing.StartSpanFromContext
in the read path packages.

Packages: querier, queryfrontend, querybackend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace opentracing.StartSpanFromContext with dskit tracing.StartSpanFromContext
in the storage engine and compaction packages.

Packages: phlaredb, phlaredb/block, phlaredb/query, phlaredb/symdb,
compactor, compactionworker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace opentracing.StartSpanFromContext with dskit tracing.StartSpanFromContext
in the metastore and VCS packages.

Packages: metastore, metastore/fsm, metastore/raftnode, frontend/vcs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace OpenTracing-specific integration code with OTel equivalents:

- spanlogger: switch to spanlogger.NewOTel()
- httpgrpcutil/carrier: add OTel propagation.TextMapCarrier interface
- frontend: replace tracer.Inject with otel.GetTextMapPropagator().Inject
- scheduler: replace OpenTracing extraction with OTel propagation
- querier/worker: replace OpenTracing extraction with OTel propagation
- gRPC clients: replace otgrpc interceptors with otelgrpc.NewClientHandler
- HTTP transport: replace nethttp.TraceRequest with otelhttp.NewTransport
- objstore: switch from opentracing to opentelemetry tracing wrapper
- Delete pkg/util/nethttp/client.go (no longer needed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
aleks-p and others added 15 commits March 31, 2026 08:45
Replace the OpenTracing tracer initialization with an OTel TracerProvider:
- Use dskit's NewOTelOrJaegerFromEnv (understands existing JAEGER_* env vars)
- Fall back to direct OTel SDK init if dskit hits schema URL conflicts
- Move opentracing-go, opentracing-contrib/go-grpc, jaeger-client-go
  from direct to indirect dependencies
- Remove OpenTracing tracer registration from modules.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update stale references to opentracing-go and spanprofiler in CLAUDE.md
and example READMEs to reflect the switch to OpenTelemetry and
otel-profiling-go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix scheduler "queued" span to inherit trace parent from HTTP request
  headers, so it appears in the correct distributed trace
- Migrate symbolizer.go from OpenTracing to OTel (was missed)
- Guard HttpgrpcHeadersCarrier.Get against empty Values slice panic
- Remove dead ForeachKey method (OpenTracing TextMapReader remnant)
- Narrow initTracing fallback to only schema URL conflict errors
- Convert sequential SetTag("msg",...) to AddEvent() to preserve
  intermediate progress events as timestamped span events
- Fix gofmt issues (import ordering, trailing newlines)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…port

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add SetError() after every LogError() call so error spans are properly
  marked in trace backends (Tempo/Jaeger) — 34 call sites across 16 files
- Replace fragile string-matching fallback in initTracing with
  unconditional fallback to direct OTel SDK init on any dskit failure
- Convert repeated SetTag calls in parquet iterator hot paths (iters.go,
  repeated.go) to AddEvent with attributes, preserving per-page telemetry
- Harden verify.sh: fail on query errors, detect Tempo failures, verify
  trace depth (context propagation), add timestamps, reduce startup time
- Use --extra-labels and --query in verify.sh so uploaded profiles are
  immediately queryable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Preserve gRPC stream cancellation in scheduler_processor by grafting
the extracted span context onto the stream context instead of
context.Background(). Use AddEvent instead of SetAttributes for
concurrent per-replica profile merge diagnostics. Restore conditional
span creation in metastore tracing to avoid orphaned root spans on
follower nodes. Prefer OTEL_SERVICE_NAME over JAEGER_SERVICE_NAME.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SetTag overwrites on each iteration, losing per-batch/per-row-group
diagnostic data. Switch to AddEvent to preserve all iterations, matching
the pattern used elsewhere in the codebase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace SetTag("msg", ...) with AddEvent to preserve the original
LogFields/LogKV semantics as timestamped span events. Also restore the
dropped shouldSymbolize span event in the symbolizer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…exts

context.WithoutCancel preserves all parent values, but the old code
explicitly injected tenant ID from the request struct. Restore this to
avoid relying on tenant ID being in the parent context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The compaction loop can run multiple iterations; SetTag would overwrite
previous values. Use AddEvent to preserve per-iteration counts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Upgrade dskit to latest main which uses OTel v1.41.0, resolving the
schema URL conflict between dskit's semconv (1.34.0) and the SDK's
bundled semconv (1.39.0) that caused NewOTelOrJaegerFromEnv to fail.

Also fix breaking API changes from the dskit/prometheus upgrades:
- ring.ReadRing now requires Zones() method
- ring.Desc.AddIngester now takes InstanceVersions parameter
- relabel.Config.Validate now takes ValidationScheme parameter
- relabel.Process removed, use ProcessBuilder instead
- labels.MetricName deprecated, use model.MetricNameLabel
- Update memberlist fork to match dskit's replace directive

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Run make generate to update config docs with new dskit flags
- Fix relabel test: empty rule is now valid with UTF8 validation
- Validate defaultRelabelRules before ProcessBuilder to set scheme
- Use nil-safe protobuf getters in query_log.go to avoid panic in
  dskit's KeyValueToOTelAttribute when Stringer values are nil

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aleks-p
aleks-p force-pushed the chore/switch-to-otel-tracing branch from 5410657 to 00d32bf Compare March 31, 2026 11:56
@aleks-p
aleks-p merged commit 087fd87 into main Mar 31, 2026
27 checks passed
@aleks-p
aleks-p deleted the chore/switch-to-otel-tracing branch March 31, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants